package org.tool.io.file;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件系统工具类
 *
 * @author 李坤
 * @date 2022/4/17 1:33
 */
public abstract class FileUtil {

    /**
     * 是否为Windows环境
     *
     * @return 是否为Windows环境
     */
    public static boolean isWindows() {
        return FileNameConstant.WINDOWS_SEPARATOR == File.separatorChar;
    }

    /**
     * 生成给定路径的文件（如果父级目录不存在，则同步创建父级目录）
     *
     * @param path 文件路径
     *
     * @return 文件
     *
     * @throws IOException IO异常
     */
    public static File getFile(String path) throws IOException {
        return FileUtil.getFile(new File(path));
    }


    /**
     * 生成给定路径的文件（如果父级目录不存在，则同步创建父级目录）
     *
     * @param path 文件路径
     *
     * @return 文件
     *
     * @throws IOException IO异常
     */
    public static File getFile(Path path) throws IOException {
        return FileUtil.getFile(path.toFile());
    }

    /**
     * 获取给定目录下的所有文件
     *
     * @param file   目录路径
     * @param ignore 忽略处理的目录/文件名称
     *
     * @return 目下的所有文件
     */
    public static List<File> getFileList(File file, String... ignore) {
        return getFileList(file, Arrays.stream(ignore).collect(Collectors.toSet()));
    }

    /**
     * 获取给定目录下的所有文件
     *
     * @param file   目录路径
     * @param ignore 忽略处理的目录/文件名称
     *
     * @return 目下的所有文件
     */
    public static List<File> getFileList(File file, Collection<String> ignore) {
        if (file.isDirectory()) {
            final List<File> fileList = new ArrayList<>();

            for (File inner : file.listFiles()) {
                if (!isMatch(ignore, inner)) {
                    if (inner.isFile()) {
                        fileList.add(inner);
                    } else {
                        fileList.addAll(getFileList(inner, ignore));
                    }
                }
            }
            return fileList;
        }
        return Collections.singletonList(file);
    }

    /**
     * 生成给定 File 对象对应的文件（如果父级目录不存在，则同步创建父级目录）
     *
     * @param file 文件对象
     *
     * @return 文件
     *
     * @throws IOException IO异常
     */
    public static File getFile(File file) throws IOException {
        // 如果文件不存在，则创建文件
        if (!(file = file.getAbsoluteFile()).exists()) {
            File parentFile = file.getParentFile();

            // 如果文件的父目录不存在，则创建父目录
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            file.createNewFile();
        }
        return file;
    }


    /*--------------------------------------------------------------------------------------*/


    /**
     * 判断给定的文件是否在被忽略名单中
     *
     * @param ignore 被忽略文件名单
     * @param file   需要判断的文件
     *
     * @return 判断结果；{@code true}-需要被忽略
     */
    private static boolean isMatch(Collection<String> ignore, File file) {
        final String name = file.getAbsolutePath();
        for (String path : ignore) {
            if (name.contains(path)) {
                return true;
            }
        }
        return false;
    }


    /*------------------------------------------public static abstract class------------------------------------------*/


    /**
     * 文件名称相关常量类
     */
    public static abstract class FileNameConstant {

        public static final char WINDOWS_SEPARATOR = '\\';

    }

}
